package com.wj.crm.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wj.crm.base.BaseService;
import com.wj.crm.dao.SaleChanceMapper;
import com.wj.crm.dao.UserMapper;
import com.wj.crm.dao.UserRoleMapper;
import com.wj.crm.model.UserModel;
import com.wj.crm.query.SaleChanceQuery;
import com.wj.crm.query.UserQuery;
import com.wj.crm.utils.AssertUtil;
import com.wj.crm.utils.Md5Util;
import com.wj.crm.utils.UserIDBase64;
import com.wj.crm.vo.SaleChance;
import com.wj.crm.vo.User;
import com.wj.crm.vo.UserRole;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

/**
 * @author WangJin
 * @version 1.0
 * @date 2021/12/10 11:18
 */
@Service
public class UserService extends BaseService<User,Integer> {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;
    /**
     * 用户登录
     * @param userName
     * @param userPwd
     * @return
     */
    public UserModel userLogin(String userName, String userPwd) {
    // 1. 验证参数
        checkLoginParams(userName, userPwd);
    // 2. 根据用户名，查询用户对象
        User user = userMapper.queryUserByUserName(userName);
    // 3. 判断用户是否存在 (用户对象为空，记录不存在，方法结束)
        AssertUtil.isTrue(null == user, "用户不存在或已注销！");
    // 4. 用户对象不为空（用户存在，校验密码。密码不正确，方法结束）
        checkLoginPwd(userPwd, user.getUserPwd());
    // 5. 密码正确（用户登录成功，返回用户的相关信息）
        return buildUserInfo(user);
    }
    /**
     * 构建返回的用户信息
     * @param user
     * @return
     */
    private UserModel buildUserInfo(User user) {
        UserModel userModel = new UserModel();
        // 设置用户信息
        // 设置用户信息（将 userId 加密）
        userModel.setUserIdStr(UserIDBase64.encoderUserID(user.getId()));
        userModel.setUserName(user.getUserName());
        userModel.setTrueName(user.getTrueName());
        return userModel;
    }
    /**
     * 验证登录密码
     * @param userPwd 前台传递的密码
     * @param upwd 数据库中查询到的密码
     * @return
     */
    private void checkLoginPwd(String userPwd, String upwd) {
    // 数据库中的密码是经过加密的，将前台传递的密码先加密，再与数据库中的密码作比较
        userPwd = Md5Util.encode(userPwd);
    // 比较密码
        AssertUtil.isTrue(!userPwd.equals(upwd), "用户密码不正确！");
    }
    /**
     * 验证用户登录参数
     * @param userName
     * @param userPwd
     */
    private void checkLoginParams(String userName, String userPwd) {
    // 判断姓名
        AssertUtil.isTrue(StringUtils.isBlank(userName), "用户姓名不能为空！");
    // 判断密码
        AssertUtil.isTrue(StringUtils.isBlank(userPwd), "用户密码不能为空！");
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateUserPassword(Integer userId,String oldPassword,String newPassword,String confirmPassword){
        //1.通过userId获得用户对象
        User user = userMapper.selectByPrimaryKey(userId);
        //2.参数校验
        checkPasswordParams(user,oldPassword,newPassword,confirmPassword);
        //3.设置用户新密码
        user.setUserPwd(Md5Util.encode(newPassword));
        //4.执行更新操作
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user)<1,"用户密码更新失败！");
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public  UserModel updateInformation(Integer userId, String userName,String email, String phone){
        //1.通过userId获得用户对象
        User user = userMapper.selectByPrimaryKey(userId);
        //2.参数校验
        checkUserParams(userName, email,phone ,userId);
        user.setUserName(userName);
        user.setEmail(email);
        user.setPhone(phone);
        //设置默认值
        user.setUpdateDate(new Date());
        //3.执行更新操作，判断影响行数
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) != 1,"更新用户失败！");

        return buildUserInfo(user);
    }



    /**
     * 验证用户密码修改参数
     * 用户ID：userId 非空 用户对象必须存在
     * 原始密码：oldPassword 非空 与数据库中密文密码保持一致
     * 新密码：newPassword 非空 与原始密码不能相同
     * 确认密码：confirmPassword 非空 与新密码保持一致
     * @param user
     * @param oldPassword
     * @param newPassword
     * @param confirmPassword
     */
    private void checkPasswordParams(User user,String oldPassword,String newPassword,String confirmPassword){
        //user对象非空校验
        AssertUtil.isTrue(null == user,"用户登陆不存在！");
        //原始密码不能为空
        AssertUtil.isTrue(StringUtils.isBlank(oldPassword),"请输入原始密码！");
        //原始密码要与数据库中的密文密码保持一致
        AssertUtil.isTrue(!(user.getUserPwd().equals(Md5Util.encode(oldPassword))),"原始密码不正确！");
        //新密码非空校验
        AssertUtil.isTrue(StringUtils.isBlank(newPassword),"请输入新密码！");
        // 新密码与原始密码不能相同
        AssertUtil.isTrue(oldPassword.equals(newPassword), "新密码不能与原始密码相同！");
        // 确认密码 非空校验
        AssertUtil.isTrue(StringUtils.isBlank(confirmPassword), "请输入确认密码！");
        // 新密码要与确认密码保持一致
        AssertUtil.isTrue(!(newPassword.equals(confirmPassword)), "新密码与确认密码不一致！");

    }

    /**
     * 查询所有的销售人员
     * @return
     */
    public List<Map<String, Object>> queryAllSales() {
        return userMapper.queryAllSales();
    }

    /**
     * 多条件分页查询营销机会 (BaseService 中有对应的方法)
     * @param query
     * @return
     */
    public Map<String, Object> selectByParams (UserQuery query) {
        Map<String, Object> map = new HashMap<>();
        PageHelper.startPage(query.getPage(), query.getLimit());
        PageInfo<User> pageInfo = new PageInfo<>(userMapper.selectByParams(query));
        map.put("code",0);
        map.put("msg", "success");
        map.put("count", pageInfo.getTotal());
        map.put("data", pageInfo.getList());
        return map;
    }

   @Transactional(propagation = Propagation.REQUIRED)
    public void addUser(User user){
        //1.参数校验
       checkUserParams(user.getUserName(),user.getEmail(),user.getPhone(),null);
       //2.设置参数的默认值
       user.setIsValid(1);
       user.setCreateDate(new Date());
       user.setUpdateDate(new Date());
       //设置默认密码
       user.setUserPwd(Md5Util.encode("123456"));
       //3.执行添加操作，判断影响行数
       AssertUtil.isTrue(userMapper.insertSelective(user) != 1,"添加用户失败！");

       //用户角色关联
       rationUserRole(user.getId(),user.getRoleIds());
    }

    private void rationUserRole(Integer userId, String roleIds) {
        /**
         * 用户角色分配
         * 原始角色不存在 添加新的角色记录
         * 原始角色存在 添加新的角色记录
         * 原始角色存在 清空所有角色
         * 原始角色存在 移除部分角色
         * 如何进行角色分配???
         * 如果用户原始角色存在 首先清空原始所有角色 添加新的角色记录到用户角色表
         */
        int count = userRoleMapper.countUserRoleByUserId(userId);
        if (count > 0) {
            AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count,
                    "用户角色分配失败!");
        }
        if (StringUtils.isNotBlank(roleIds)) {
            //重新添加新的角色
            List<UserRole> userRoles = new ArrayList<UserRole>();
            for (String s : roleIds.split(",")) {
                UserRole userRole = new UserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(Integer.parseInt(s));
                userRole.setCreateDate(new Date());
                userRole.setUpdateDate(new Date());
                userRoles.add(userRole);
            }
            //批量添加用户角色记录
            AssertUtil.isTrue(userRoleMapper.insertBatch(userRoles) !=
                    userRoles.size(), "用户角色分配失败!");
        }

    }


    public void checkUserParams(String userName,String email,String phone ,Integer userId){
        //判断用户是否为空
        AssertUtil.isTrue(StringUtils.isBlank(userName),"用户名不能为空！");
        //判断用户名的唯一性
        //通过用户查询用户对象
        User temp = userMapper.queryUserByUserName(userName);
        //如果用户对象为空，则表示用户名可用，如果用户名不为空，则表示用户名不可用
        AssertUtil.isTrue(null != temp && !(temp.getId().equals(userId)),"用户名已存在，请重新输入！");
        //邮箱非空
        AssertUtil.isTrue(StringUtils.isBlank(email),"用户邮箱不能为空！");
        //手机号非空
        AssertUtil.isTrue(StringUtils.isBlank(phone),"手机号不能为空！");
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateUser(User user){
        //判断用户ID是否为空，且数据存在
        AssertUtil.isTrue(null == user.getId(),"待更新记录不存在！");
        //通过id查询数据
        userMapper.selectByPrimaryKey(user.getId());
        //1.参数校验
        checkUserParams(user.getUserName(),user.getEmail(),user.getPhone(),user.getId());
        //设置默认值
        user.setUpdateDate(new Date());
        //3.执行更新操作，判断影响行数
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) != 1,"更新用户失败！");

        //用户角色关联
        rationUserRole(user.getId(),user.getRoleIds());
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteByIds(Integer[] ids) {
        //判断ids是否为空，长度是否大于0
        AssertUtil.isTrue(ids == null || ids.length == 0,"待删除记录不存在！");
        //执行删除操作，判断受影响行数
        AssertUtil.isTrue(userMapper.deleteBatch(ids) != ids.length,"用户删除失败！");

        //遍历用户Id的数组
        for(Integer userId : ids){
            //通过用户Id查询对应的用户角色记录
            Integer count = userRoleMapper.countUserRoleByUserId(userId);
            //判断用户角色记录是否存在
            if(count > 0){
                //通过用户id删除对应的用户角色记录
                AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count,"删除用户失败！");
            }

        }
    }

    /**
     * 查询所有的客户经理
     *
     * @param
     * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     */
    public List<Map<String, Object>> queryAllCustomerManagers() {
        return userMapper.queryAllCustomerManagers();
    }
}
